#ifndef FASTCGI_H
#define FASTCGI_H

#include "buffer.h"
#include "http_connection.h"

/* Listening socket file number. */
#define FCGI_LISTENSOCK_FILENO   0

typedef struct {
	unsigned char version;
	unsigned char type;
	unsigned char requestIdB1;
	unsigned char requestIdB0;
	unsigned char contentLengthB1;
	unsigned char contentLengthB0;
	unsigned char paddingLength;
	unsigned char reserved;
} FCGI_Header;

/* Number of bytes in a FCGI_Header. Future versions of the protocol will not reduce this number. */
#define FCGI_HEADER_LEN          8

/* Value for version component of FCGI_Header. */
#define FCGI_VERSION_1           1

/* Values for type component of FCGI_Header. */
#define FCGI_BEGIN_REQUEST       1
#define FCGI_ABORT_REQUEST       2
#define FCGI_END_REQUEST         3
#define FCGI_PARAMS              4
#define FCGI_STDIN               5
#define FCGI_STDOUT              6
#define FCGI_STDERR              7
#define FCGI_DATA                8
#define FCGI_GET_VALUES          9
#define FCGI_GET_VALUES_RESULT   10
#define FCGI_UNKNOWN_TYPE        11
#define FCGI_MAXTYPE             (FCGI_UNKNOWN_TYPE)

/* Value for requestId component of FCGI_Header. */
#define FCGI_NULL_REQUEST_ID     0

typedef struct {
	unsigned char roleB1;
	unsigned char roleB0;
	unsigned char flags;
	unsigned char reserved[5];
} FCGI_BeginRequestBody;

/* Mask for flags component of FCGI_BeginRequestBody. */
#define FCGI_KEEP_CONN           1

/* Values for role component of FCGI_BeginRequestBody. */
#define FCGI_RESPONDER           1
#define FCGI_AUTHORIZER          2
#define FCGI_FILTER              3

typedef struct {
	unsigned char appStatusB3;
	unsigned char appStatusB2;
	unsigned char appStatusB1;
	unsigned char appStatusB0;
	unsigned char protocolStatus;
	unsigned char reserved[3];
} FCGI_EndRequestBody;

/* Values for protocolStatus component of FCGI_EndRequestBody. */
#define FCGI_REQUEST_COMPLETE    0
#define FCGI_CANT_MPX_CONN       1
#define FCGI_OVERLOADED          2
#define FCGI_UNKNOWN_ROLE        3

/* Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records. */
#define FCGI_MAX_CONNS           "FCGI_MAX_CONNS"
#define FCGI_MAX_REQS            "FCGI_MAX_REQS"
#define FCGI_MPXS_CONNS          "FCGI_MPXS_CONNS"

typedef struct {
	unsigned char type;
	unsigned char reserved[7];
} FCGI_UnknownTypeBody;

typedef struct {
	FCGI_Header header;
	FCGI_UnknownTypeBody body;
} FCGI_UnknownTypeRecord;

int fastcgi_prepare_begin_request (buffer_t *buffer, unsigned short requestId);
int fastcgi_prepare_abort_request (buffer_t *buffer, unsigned short requestId);

int fastcgi_prepare_parameter_list (buffer_t *buffer, unsigned short requestId, http_connection_t *http_connection, const char *query, size_t query_len);

int fastcgi_prepare_data (buffer_t *buffer, unsigned short requestId, const char *data, size_t len);

int fastcgi_read_stdout_record (http_connection_t *http_connection);

#endif /* FASTCGI_H */
